﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SortCompare
{
    public static class Quicksort
    {
        public static int[] Sort(int[] array)
        {
            quicksort(ref array, 0, array.Length-1);

            return null;
        }
        /// <summary>
        /// Quicksorts, initial call array, 0, array.length-1
        /// </summary>
        /// <param name="input"></param>
        /// <param name="p"></param>
        /// <param name="r"></param>
        /// <param name="backwards"></param>
        public static void quicksort(ref int[] input, int p, int r)
        {
            if (p < r)
            {
                int q = Partition(ref input, p, r);
                quicksort(ref input, p, q - 1);
                quicksort(ref input, q + 1, r);
            }
                
        }

        /// <summary>
        /// Jiggles the array so that input[pivot] is moved to the index such that stuff before it is less and stuff after is more
        /// </summary>
        /// <param name="input"></param>
        /// <param name="first"></param>
        /// <param name="pivot"></param>
        /// <returns></returns>
        private static int Partition(ref int[] input, int first, int pivot)
        {
            int x = input[pivot];
            int i = first-1;
            //This currently swaps input[p] with every element in its way, this can be change to only swapping with the place it
            //needs to be
            for (int j = first; j < pivot; j++)
            {
                if (input[j] <= x)
                {
                    i++;
                    swap(ref input[i], ref input[j]);
                }
            }

            swap(ref input[pivot], ref input[++i]);
            return i;
        }

        /// <summary>
        /// Just like Pertition, but the pivot element is the first in the array, not the last
        /// </summary>
        /// <param name="input"></param>
        /// <param name="pivot"></param>
        /// <param name="last"></param>
        /// <returns></returns>
        private static int BackwardsPartition(ref int[] input, int pivot, int last)
        {
            int x = input[pivot];
            int i = last + 1;

            for (int j = last; j > pivot; j--)
            {
                if (input[j] > x)
                {
                    i--;
                    swap(ref input[i], ref input[j]);
                }
            }

            swap(ref input[pivot], ref input[--i]);
            return i;
        }

        private static void swap<T>(ref T lhs, ref T rhs)
        {
            T temp;
            temp = lhs;
            lhs = rhs;
            rhs = temp;
        }
    
    }

}
